<?
/**
 * Copyright 2007 Melange.
 *
 * This file is part of PHP-MELANGE.
 *
 * PHP-MELANGE is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * PHP-MELANGE is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with PHP-MELANGE; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * @category    Melange
 * @package     php-melange
 * @subpackage  cms
 * @copyright   Copyright (c) 2007 Jeroen Simons. All rights reserved
 * @author      Jeroen Simons <jeroen@melange.nl>
 * @link        http://www.melange.nl/
 *
 */

require_once("mvc/action/Action.php");
require_once("cms/core/util/ImageProperties.php");

class SaveAction extends Action {

    private $log;

    public function __construct() {
        $this->log =& LoggerManager::getLogger("SaveAction");
    }

    public function execute(ActionConfig &$mapping, &$form, Request &$request, Response &$response) {

        $errors = new ActionMessages();

        $formImage =& $form->getFormImage();
        $tinyImage =& $form->getTinyImage();
        $image = $tinyImage->getImageRelatedByImageId();
        $thumb = $tinyImage->getImageRelatedByThumbnailId();

        $conn = Propel::getConnection();

        $properties = new ImageProperties($form->getResize());

        try {

            $conn->begin();

            if(strlen($form->getPath()) == 0) {

                // Process 1 image
                if($this->log->isDebugEnabled())
                    $this->log->debug("Processing single image.");

                $this->processImage(
                    $conn, $errors, $formImage,
                    $properties, $image, $thumb, $tinyImage
                );

            } else {

                // Process multiple images
                if($this->log->isDebugEnabled())
                    $this->log->debug("Processing multiple images.");

                $this->processImages(
                    $conn, $errors, $properties, $request, $form->getPath()
                );

            }

            $conn->commit();

        } catch (Exception $e) {
            $conn->rollback();
            if($errors->isEmpty())
                $errors->add(ActionMessage::GLOBAL_MESSAGE,
                    new ActionMessage("error.save", true));
            $this->log->error($e);
        }


        // Return any save errors.
        if(!$errors->isEmpty()) {
            $this->saveErrors($request, $errors);
            return $mapping->getInputForward();
        }


        // Reset the imageListForm from & to session.
        $session  = $request->getSession();
        $listForm = $session->getAttribute("php-cms/imageListForm");
        if(!is_null($listForm)) {
            $listForm->setPage(1);
            $session->setAttribute("php-cms/imageListForm", $listForm);
        }


        // To the success page.
        return $mapping->findForward("success");

    }


    // -------------------------------------------------------- Private Methods


    /**
     * Process 1 image uploaded by a file input field.
     *
     * @param conn The Propel database connection.
     * @param errors The MVC ActionErrors.
     * @param formImage The uploaded php image array.
     * @param properties The resize properties.
     * @param image The Image Propel Object.
     * @param thumb The Image Propel Object.
     * @param tinyImage The TinyImage Propel Object.
     */
    private function processImage(Connection $conn, ActionMessages &$errors, $formImage,
            ImageProperties $properties, Image $image, Image $thumb, TinyImage $tinyImage) {

        if(!is_uploaded_file($formImage["tmp_name"])) {
            $errors->add(ActionMessage::GLOBAL_MESSAGE,
                new ActionMessage("No image was uploaded."));
            throw new Exception("No image was uploaded.");
        }

        // Create temporary filenames.
        $temp = $formImage["tmp_name"].".temp";

        // Get the original image dimensions.
        $size = getimagesize($formImage["tmp_name"]);

        require_once ("cms/core/util/Image_Toolbox.class.php");
        $img = new Image_Toolbox($formImage["tmp_name"]);
        $img->setResizeMethod("resample");


        $image->setSecure($properties->getSecure());
        $thumb->setSecure($properties->getSecure());


        // Image resizing.
        if(($properties->getImageAxis() == "x" && $size[0] > $properties->getImageWidth()) ||
           ($properties->getImageAxis() == "y" && $size[1] > $properties->getImageHeight())) {

            if($this->log->isDebugEnabled())
                $this->log->debug("Saving resized image.");

            $img->newOutputSize($properties->getImageWidth(), $properties->getImageHeight(), 1);
            $img->save($temp);

            $image->saveFile($temp, $formImage["name"], $conn);

        } else {

            if($this->log->isDebugEnabled())
                $this->log->debug("Saving original image.");

            $image->saveForm($formImage, $conn);

        }


        // Thumbnail resizing.
        if(($properties->getThumbAxis() == "x" && $size[0] > $properties->getThumbWidth()) ||
           ($properties->getThumbAxis() == "y" && $size[1] > $properties->getThumbHeight())) {

            require_once ("cms/core/util/Image_Toolbox.class.php");

            if($this->log->isDebugEnabled())
                $this->log->debug("Saving resized thumbnail.");

            $img->newOutputSize($properties->getThumbWidth(), $properties->getThumbHeight(), 1);
            $img->save($temp);

            $thumb->saveFile($temp, $formImage["name"], $conn, "thumb_");

        } else {

            if($this->log->isDebugEnabled())
                $this->log->debug("Saving original thumbnail.");

            $thumb->saveForm($formImage, $conn, "thumb_");

        }

        // Delete the tmp file
        if(file_exists($temp)) unlink($temp);

        // Set the generated ids
        $tinyImage->setThumbnailId($thumb->getImageId());
        $tinyImage->setImageId($image->getImageId());

        if($tinyImage->getTinyImageId() > 0) {
            TinyImagePeer::doUpdate($tinyImage, $conn);
        } else {
            TinyImagePeer::doInsert($tinyImage, $conn);
        }

    }


    /**
     * Process multiple images specified by a FTP directory input field.
     *
     * @param conn The Propel database connection.
     * @param errors The MVC ActionErrors.
     * @param properties The resize properties.
     * @param request The request used for this processing.
     * @param path The FTP directory
     */
    private function processImages(Connection $conn, ActionMessages &$errors,
            ImageProperties $properties, Request $request, $path) {

        $path = (strpos($path, "/") === 0 ? $path : "/".$path);
        $real = $request->getContext()->getRealPath($path);

        if(!is_writable($real)) {
            $errors->add(ActionMessage::GLOBAL_MESSAGE,
                new ActionMessage("Directory has no write permissions."));
            throw new Exception("Directory has no write permissions.");
        }

        require_once ("cms/core/util/Image_Toolbox.class.php");

        $handle = opendir($real);

        // Loop over the directory.
        while (false !== ($file = readdir($handle))) {

            if($file != "." && $file != "..") {

                // Get the original image dimensions.
                $size = getimagesize($real."/".$file);

                // Is this an image
                if(isset($size[0])) {

                    $image = new Image($properties->getSecure());
                    $image->setSecure($properties->getSecure());

                    $thumb = new Image();
                    $thumb->setSecure($properties->getSecure());

                    $filename = $real."/".$file;

                    // Create temporary filenames.
                    $temp = $filename.".temp";

                    $img = new Image_Toolbox($filename);
                    $img->setResizeMethod("resample");

                    // Image resizing.
                    if(($properties->getImageAxis() == "x" && $size[0] > $properties->getImageWidth()) ||
                       ($properties->getImageAxis() == "y" && $size[1] > $properties->getImageHeight())) {

                        $img->newOutputSize($properties->getImageWidth(), $properties->getImageHeight(), 1);
                        $img->save($temp);

                        $image->saveFile($temp, basename($filename), $conn);

                        if($this->log->isDebugEnabled())
                            $this->log->debug("Saving resized image " . $filename);

                    } else {

                        if($this->log->isDebugEnabled())
                            $this->log->debug("Saving original image " . $filename);

                        $image->saveFile($filename, null, $conn);

                    }

                    // Delete the tmp file
                    if(file_exists($temp)) unlink($temp);

                    // Thumb resizing.
                    if(($properties->getThumbAxis() == "x" && $size[0] > $properties->getThumbWidth()) ||
                       ($properties->getThumbAxis() == "y" && $size[1] > $properties->getThumbHeight())) {

                        $img->newOutputSize($properties->getThumbWidth(), $properties->getThumbHeight(), 1);
                        $img->save($temp);

                        if($this->log->isDebugEnabled())
                            $this->log->debug("Saving resized thumb " . $filename);

                        $thumb->saveFile($temp, basename($filename), $conn);

                    } else {
                        if($this->log->isDebugEnabled())
                            $this->log->debug("Saving original thumb " . $filename);

                        $thumb->saveFile($filename, null, $conn);
                    }

                    // Delete the tmp file
                    if(file_exists($temp)) unlink($temp);

                    // Save the parent
                    $ti = new TinyImage();
                    $ti->setThumbnailId($thumb->getImageId());
                    $ti->setImageId($image->getImageId());
                    TinyImagePeer::doInsert($ti, $conn);

                }

            }

        }

        closedir($handle);

    }


}
?>